#include <SDL2/SDL.h>
#include <stdio.h>
#include <string.h>

// https://wiki.libsdl.org/SDL_GameControllerAddMapping?highlight=%28%5CbCategoryGameController%5Cb%29%7C%28CategoryEnum%29
// https://www.libsdl.org/release/SDL-1.2.15/docs/html/guideinput.html
// https://www.libsdl.org/release/SDL-1.2.15/docs/html/joystick.html
// https://www.libsdl.org/release/SDL-1.2.15/docs/html/eventstructures.html

static void map_test()
{
	/*
	bX      a joystick button, index X
	hX.Y    hat X with value Y
	aX      axis X of the joystick
	Buttons can be used as a controller axes and vice versa.

	This string shows an example of a valid mapping for a controller:
	"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7"
	 */
	SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(0);
	char s_guid[1024];

	char *ms = ",Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7";

	SDL_JoystickGetGUIDString(guid, s_guid, 256);
	int status = SDL_GameControllerAddMapping(s_guid);

	printf("map guid:[%s] status: %d\n", s_guid, status);
	strcat(s_guid, ms);
	printf("map string: %s\n", s_guid);
	status = SDL_GameControllerAddMapping(s_guid);
	printf("map guid:[%s] status: %d\n", s_guid, status);
}

static void info()
{
	for (int i = 0; i < SDL_NumJoysticks(); ++i) {
		if (SDL_IsGameController(i)) {
			printf("inx [%d] joystick is SDL_IsGameController\n", i);
		} else {
			printf("inx [%d] joystick is not SDL_IsGameController\n", i);
		}
		const char *name = SDL_GameControllerNameForIndex(i);
		if (name) {
			printf("Joystick %i has game controller name '%s'\n", i, name);
		} else {
			printf("Joystick %i has no game controller name.\n", i);
		}
	}

	/* Open the first available controller. */
	SDL_GameController *controller = NULL;
	for (int i = 0; i < SDL_NumJoysticks(); ++i) {
		if (SDL_IsGameController(i)) {
			controller = SDL_GameControllerOpen(i);
			if (controller) {
				break;
			} else {
				fprintf(stderr, "Could not open gamecontroller %i: %s\n", i, SDL_GetError());
			}
		}
	}
	if (controller != NULL) {
		SDL_GameControllerClose(controller);
	}

	SDL_GameController *ctrl;

	for (int i = 0; i < SDL_NumJoysticks(); ++i) {
		if (SDL_IsGameController(i) || 1) {
			char *mapping;
			SDL_Log("Index \'%i\' is a compatible controller, named \'%s\'", i, SDL_GameControllerNameForIndex(i));
			ctrl = SDL_GameControllerOpen(i);
			mapping = SDL_GameControllerMapping(ctrl);
			SDL_Log("Controller %i is mapped as \"%s\".", i, mapping);
			SDL_free(mapping);
			SDL_GameControllerClose(ctrl);
		} else {
			SDL_Log("Index \'%i\' is not a compatible controller.", i);
		}
	}
}

static void envent_test()
{

	SDL_Joystick *joystick;
	SDL_JoystickEventState(SDL_ENABLE);
	SDL_GameControllerEventState(SDL_ENABLE);
	SDL_GameController *ctrl;
	ctrl = SDL_GameControllerOpen(0);

	int quit = 0;
	SDL_Event event;
	while (!quit)
		while (SDL_PollEvent(&event)) {
			printf("=======%d\n", event.type);
			switch (event.type) {
			case SDL_KEYDOWN:
				printf("event name SDL_KEYDOWN: val: %d\n", event.type);
				/* handle keyboard stuff here */
				break;
			case SDL_QUIT:
				quit = 1;
				printf("event name SDL_QUIT: val: %d\n", event.type);
				/* Set whatever flags are necessary to */
				/* end the main game loop here */
				break;
			case SDL_CONTROLLERBUTTONDOWN:
				printf("event type: %d, => SDL_CONTROLLERBUTTONDOWN\n", event.type);
				// if (event.cbutton.state == SDL_PRESSED) {
				// 	auto code = getKeycodeForButton((SDL_GameControllerButton)event.cbutton.button);
				// 	if (code != NKCODE_UNKNOWN) {
				// 		KeyInput key;
				// 		key.flags = KEY_DOWN;
				// 		key.keyCode = code;
				// 		key.deviceId = DEVICE_ID_PAD_0 + getDeviceIndex(event.cbutton.which);
				// 		NativeKey(key);
				// 	}
				// }
				break;
			case SDL_CONTROLLERBUTTONUP:
				printf("event type: %d, => SDL_CONTROLLERBUTTONUP\n", event.type);
				// if (event.cbutton.state == SDL_RELEASED) {
				// 	auto code = getKeycodeForButton((SDL_GameControllerButton)event.cbutton.button);
				// 	if (code != NKCODE_UNKNOWN) {
				// 		KeyInput key;
				// 		key.flags = KEY_UP;
				// 		key.keyCode = code;
				// 		key.deviceId = DEVICE_ID_PAD_0 + getDeviceIndex(event.cbutton.which);
				// 		NativeKey(key);
				// 	}
				// }
				break;
			case SDL_CONTROLLERAXISMOTION:
				printf("event type: %d, => SDL_CONTROLLERAXISMOTION\n", event.type);
				// AxisInput axis;
				// axis.axisId = event.caxis.axis;
				// // 1.2 to try to approximate the PSP's clamped rectangular range.
				// axis.value = 1.2 * event.caxis.value * g_Config.fXInputAnalogSensitivity / 32767.0f;
				// if (axis.value > 1.0f) axis.value = 1.0f;
				// if (axis.value < -1.0f) axis.value = -1.0f;
				// axis.deviceId = DEVICE_ID_PAD_0 + getDeviceIndex(event.caxis.which);
				// axis.flags = 0;
				// NativeAxis(axis);
				break;
			case SDL_CONTROLLERDEVICEREMOVED:
				printf("event type: %d, => SDL_CONTROLLERDEVICEREMOVED\n", event.type);
				// for removal events, "which" is the instance ID for SDL_CONTROLLERDEVICEREMOVED
				// for (auto it = controllers.begin(); it != controllers.end(); ++it) {
				// 	if (SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(*it)) == event.cdevice.which) {
				// 		SDL_GameControllerClose(*it);
				// 		controllers.erase(it);
				// 		break;
				// 	}
				// }
				break;
			case SDL_CONTROLLERDEVICEADDED:
				printf("event type: %d, => SDL_CONTROLLERDEVICEADDED\n", event.type);
				// for add events, "which" is the device index!
				// int prevNumControllers = controllers.size();
				// setUpController(event.cdevice.which);
				// if (prevNumControllers == 0 && controllers.size() > 0) {
				// 	cout << "pad 1 has been assigned to control pad: " << SDL_GameControllerName(controllers.front()) << endl;
				// }
				break;
			default:
				printf("event type: %d, => Default\n", event.type);
				break;
			}
		}
}

// #define SDL_JoystickOpen
int main(int argc, char const * argv[])
{

	//我们要渲染的窗口
	SDL_Window* window = NULL;

	if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0)
	{
		fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
		exit(1);
	}

	//创建窗口
	window = SDL_CreateWindow("MY FIRST SDL WINDOW", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 33, 333, SDL_WINDOW_SHOWN);
	if (NULL == window)
	{
		SDL_Quit();
		return -1;
	}
	map_test();
	info();
	envent_test();

	// while(1)
	//等待两秒
	// SDL_Delay(2000);

	SDL_Quit();
	return 0;
}